/*
 * Copyright (c) 2024 BI1NDG_Zhouyuling AND BI1NDF_Duanyuyan
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//库函数
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_uart.h"
#include "pinctrl.h"
#include "uart.h"
#include "iot_watchdog.h"
#include "iot_gpio_ex.h"

//SLE库函数
#include "securec.h"
#include "sle_common.h"
#include "osal_debug.h"
#include "sle_errcode.h"
#include "osal_addr.h"
#include "osal_task.h"
#include "sle_connection_manager.h"
#include "sle_device_discovery.h"
#include "SLE_BEACON_ADV.h"
#include "SLE_BEACON.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
#include "ohos_sle_common.h"
#include "ohos_sle_errcode.h"
#include "ohos_sle_ssap_server.h"
#include "ohos_sle_ssap_client.h"
#include "ohos_sle_device_discovery.h"
#include "ohos_sle_connection_manager.h"
#include "errcode.h"

//GPS设置
#define Satellite_RX_PIN 15
#define Satellite_TX_PIN 16
#define Satellite_RATE 9600
#define Satellite_DATABITS 3
#define Satellite_STOPBITS 1
#define Satellite_PARITYBIT 0
#define Satellite_SIZE 256
#define Satellite_BUSID 1
static uint8_t ReadBuff[Satellite_SIZE];
static uint8_t Satellite_NUM=0;
static char SLE_latitude[16] = {0};
static char Send_SLE_latitude[20] = {0};
static char SLE_longitude[16] = {0};
static char Send_SLE_longitude[20] = {0};

//蜂鸣器设置
#define BEEP_PIN 12

//LED设置
#define LED_PIN 14

//时钟设置
#define DELAY_100MS 100
#define DELAY_200MS 200
#define DELAY_500MS 500
#define DELAY_1000MS 1000
#define DELAY_2000MS 2000
#define DELAY_3000MS 3000
#define DELAY_5000MS 5000
#define DELAY_10000MS 10000

//SLE设置
#define OCTET_BIT_LEN 8
#define UUID_LEN_2 2
#define UUID_INDEX 14
#define BT_INDEX_4     4
#define BT_INDEX_0     0
#define UART_BUFF_LENGTH    0x100
#define SLE_ADV_HANDLE_DEFAULT                    1
static char g_sle_uuid_app_uuid[UUID_LEN_2] = { 0x12, 0x34 };
static char g_sle_property_value[OCTET_BIT_LEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
static uint16_t g_sle_conn_hdl = 0;
static uint8_t g_server_id = 0;
static uint16_t g_service_handle = 0;
static uint16_t g_property_handle = 0;
uint16_t g_sle_pair_hdl;
#define UUID_16BIT_LEN 2
#define UUID_128BIT_LEN 16
#define sample_at_log_print(fmt, args...) osal_printk(fmt, ##args)
#define SLE_BEACON_LOG "[SLE_BEACON]"
#define SLE_SERVER_INIT_DELAY_MS    1000
static sle_uart_server_msg_queue g_sle_uart_server_msg_queue = NULL;
static uint8_t g_sle_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t g_at_pre_char = 0;
static uint32_t g_at_uart_recv_cnt = 0;
#define SLE_UART_TRANSFER_SIZE              256

static void SOSCall()
{
    // 初始化GPIO
    IoTGpioInit(BEEP_PIN);
    IoTGpioInit(LED_PIN);
    // 设置引脚功能为MODE_0(GPIO)
    IoSetFunc(BEEP_PIN, IOT_IO_FUNC_GPIO_12_GPIO);
    IoSetFunc(LED_PIN, IOT_IO_FUNC_GPIO_14_GPIO);
    // 设置GPIO为输出方向
    IoTGpioSetDir(BEEP_PIN, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(LED_PIN, IOT_GPIO_DIR_OUT);
    // 配置GPIO引脚号和输出值
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    //O
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_500MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_500MS);
    //S
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_100MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_5000MS);
    return NULL; 
}

static void Satellite_RX_callback(const void *buffer, uint16_t length, bool error)
{
    TaskMsleep(DELAY_10000MS);
    //printf("Satellite_BUFFER:%s\r\n", (const char *)buffer);
    if(strncmp((const char *)buffer, "$GNGGA", 6) == 0)
    {
        ReadBuff[0] = '\0';
        Satellite_NUM = 0;
    }
    if(Satellite_NUM<5)
    {
        strncat(ReadBuff, buffer, length);
        Satellite_NUM = Satellite_NUM+1;
    }
    else
    {
        //printf("Satellite_ReadBuffer:%s\r\n", ReadBuff);
        char latitude[16] = {0};
        char longitude[16] = {0};
        const char *ptr = (char *)ReadBuff + 7;
        ptr = strchr(ptr, ',') + 1;
        char *lat_end = strchr(ptr, ',');
        strncpy(latitude, ptr, lat_end - ptr);
        latitude[lat_end - ptr] = '\0';
        ptr = lat_end + 3;
        char *lon_end = strchr(ptr, ',');
        strncpy(longitude, ptr, lon_end - ptr);
        longitude[lon_end - ptr] = '\0';
        //printf("+++Latitude+++\r\n");
        //printf("SLE_Latitude: %s\r\n", SLE_latitude);
        //uart_sle_send_data(latitude,16);
        if(strcmp(latitude,SLE_latitude)!=0)
        {
            //uart_sle_send_data("BEACON_LAT:",16);
            //uart_sle_send_data(latitude,16);
            //printf("Latitude: %s\r\n", latitude);
            strcpy(Send_SLE_latitude, "LAT:");
            strncat(Send_SLE_latitude, latitude, 16);
            uart_sle_send_data(Send_SLE_latitude, 16);
            strcpy(SLE_latitude,latitude);
            printf("SLE_BEACON_%s\r\n", Send_SLE_latitude);
            strcpy(Send_SLE_latitude, "");
        }
        //printf("+++longitude+++\r\n");
        //printf("SLE_Longitude: %s\r\n", SLE_longitude);
        //uart_sle_send_data(longitude,16);
        if(strcmp(longitude,SLE_longitude)!=0)
        {
            //uart_sle_send_data("BEACON_LON:",16);
            //uart_sle_send_data(longitude,16);
            //printf("Longitude: %s\r\n", longitude);
            strcpy(Send_SLE_longitude, "LON:");
            strncat(Send_SLE_longitude, longitude, 16);
            uart_sle_send_data(Send_SLE_longitude, 16);
            strcpy(SLE_longitude,longitude);
            printf("SLE_BEACON_%s\r\n", Send_SLE_longitude);
            strcpy(Send_SLE_longitude, "");
            
        }
    }
}

static void Satellite_config()
{
    uapi_uart_deinit(1);
    IotUartAttribute g_uart_cfg = {9600, 8, 1, IOT_UART_PARITY_NONE, 100, 100, 0}; 
    IoTUartInit(1, &g_uart_cfg);
    (void)uapi_uart_register_rx_callback(1, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, Satellite_SIZE, Satellite_RX_callback);
}

static void encode2byte_little(uint8_t *_ptr, uint16_t data)
{
    *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 0x8);
    *(uint8_t *)(_ptr) = (uint8_t)(data);
}

static void sle_uuid_set_base(SleUuid *out)
{
    errcode_t ret;
    ret = memcpy_s(out->uuid, SLE_UUID_LEN, g_sle_base, SLE_UUID_LEN);
    if (ret != EOK) {
        sample_at_log_print("%s sle_uuid_set_base memcpy fail\n", SLE_BEACON_LOG);
        out->len = 0;
        return ;
    }
    out->len = UUID_LEN_2;
}

static void sle_uuid_setu2(uint16_t u2, SleUuid *out)
{
    sle_uuid_set_base(out);
    out->len = UUID_LEN_2;
    encode2byte_little(&out->uuid[UUID_INDEX], u2);
}

static void sle_uart_uuid_print(SleUuid *uuid)
{
    if (uuid == NULL)
    {
        sample_at_log_print("%s uuid_print,uuid is null\r\n", SLE_BEACON_LOG);
        return;
    }
    if (uuid->len == UUID_16BIT_LEN)
    {
        sample_at_log_print("%s uuid: %02x %02x.\n", SLE_BEACON_LOG, uuid->uuid[14], uuid->uuid[15]);
    }
    else if (uuid->len == UUID_128BIT_LEN)
    {
        sample_at_log_print("%s uuid: \n", SLE_BEACON_LOG);
        sample_at_log_print("%s 0x%02x 0x%02x 0x%02x \n", SLE_BEACON_LOG, uuid->uuid[0], uuid->uuid[1], uuid->uuid[2], uuid->uuid[3]);
        sample_at_log_print("%s 0x%02x 0x%02x 0x%02x \n", SLE_BEACON_LOG, uuid->uuid[4], uuid->uuid[5], uuid->uuid[6], uuid->uuid[7]);
        sample_at_log_print("%s 0x%02x 0x%02x 0x%02x \n", SLE_BEACON_LOG, uuid->uuid[8], uuid->uuid[9], uuid->uuid[10], uuid->uuid[11]);
        sample_at_log_print("%s 0x%02x 0x%02x 0x%02x \n", SLE_BEACON_LOG, uuid->uuid[12], uuid->uuid[13], uuid->uuid[14], uuid->uuid[15]);
    }
}

static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id,  SsapcExchangeInfo *mtu_size, errcode_t status)
{
    sample_at_log_print("%s ssaps ssaps_mtu_changed_cbk callback server_id:%x, conn_id:%x, mtu_size:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, conn_id, mtu_size->mtuSize, status);
    if (g_sle_pair_hdl == 0)
    {
        g_sle_pair_hdl = conn_id + 1;
    }
}

static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status)
{
    sample_at_log_print("%s start service cbk callback server_id:%d, handle:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, handle, status);
}

static void ssaps_add_service_cbk(uint8_t server_id, SleUuid *uuid, uint16_t handle, errcode_t status)
{
    sample_at_log_print("%s add service cbk callback server_id:%x, handle:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, handle, status);
    sle_uart_uuid_print(uuid);
}

static void ssaps_add_property_cbk(uint8_t server_id, SleUuid *uuid, uint16_t service_handle, uint16_t handle, errcode_t status)
{
    sample_at_log_print("%s add property cbk callback server_id:%x, service_handle:%x,handle:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, service_handle, handle, status);
    sle_uart_uuid_print(uuid);
}

static void ssaps_add_descriptor_cbk(uint8_t server_id, SleUuid *uuid, uint16_t service_handle,
    uint16_t property_handle, errcode_t status)
{
    sample_at_log_print("%s add descriptor cbk callback server_id:%x, service_handle:%x, property_handle:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, service_handle, property_handle, status);
    sle_uart_uuid_print(uuid);
}

static void ssaps_delete_all_service_cbk(uint8_t server_id, errcode_t status)
{
    sample_at_log_print("%s delete all service callback server_id:%x, status:%x\r\n", SLE_BEACON_LOG, server_id, status);
}

static errcode_t sle_ssaps_register_cbks(SsapsReadRequestCallback ssaps_read_callback, SsapsWriteRequestCallback ssaps_write_callback)
{
    errcode_t ret;
    SsapsCallbacks ssaps_cbk = {0};
    ssaps_cbk.addServiceCb = ssaps_add_service_cbk;
    ssaps_cbk.addPropertyCb = ssaps_add_property_cbk;
    ssaps_cbk.addDescriptorCb = ssaps_add_descriptor_cbk;
    ssaps_cbk.startServiceCb = ssaps_start_service_cbk;
    ssaps_cbk.deleteAllServiceCb = ssaps_delete_all_service_cbk;
    ssaps_cbk.mtuChangedCb = ssaps_mtu_changed_cbk;
    ssaps_cbk.readRequestCb = ssaps_read_callback;
    ssaps_cbk.writeRequestCb = ssaps_write_callback;
    ret = SsapsRegisterCallbacks(&ssaps_cbk);
    if (ret != ERRCODE_SLE_SUCCESS) 
    {
        sample_at_log_print("%s sle_ssaps_register_cbks,ssaps_register_callbacks fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_service_add(void)
{
    errcode_t ret;
    SleUuid service_uuid = {0};
    sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid);
    ret = SsapsAddServiceSync(g_server_id, &service_uuid, 1, &g_service_handle);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle uuid add service fail, ret:%x\r\n", SLE_BEACON_LOG, ret);
        return ERRCODE_SLE_FAIL;
    }
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uuid_server_property_add(void)
{
    errcode_t ret;
    SsapsPropertyInfo property = {0};
    SsapsDescInfo descriptor = {0};
    uint8_t ntf_value[] = { 0x01, 0x02 };
    property.permissions = SLE_UUID_TEST_PROPERTIES;
    property.operateIndication = SLE_UUID_TEST_OPERATION_INDICATION;
    sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid);
    property.valueLen = OCTET_BIT_LEN;
    property.value = (uint8_t *)osal_vmalloc(sizeof(g_sle_property_value));
    if (property.value == NULL)
    {
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, sizeof(g_sle_property_value)) != EOK)
    {
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    ret = SsapsAddPropertySync(g_server_id, g_service_handle, &property,  &g_property_handle);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle uart add property fail, ret:%x\r\n", SLE_BEACON_LOG, ret);
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR;
    descriptor.type = SSAP_DESCRIPTOR_CLIENT_CONFIGURATION;
    descriptor.operateIndication = SLE_UUID_TEST_OPERATION_INDICATION;
    descriptor.value = (uint8_t *)osal_vmalloc(sizeof(ntf_value));
    if (descriptor.value == NULL)
    {
        osal_vfree(property.value);
        return ERRCODE_SLE_FAIL;
    }
    if (memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)) != EOK)
    {
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }
    ret = SsapsAddDescriptorSync(g_server_id, g_service_handle, g_property_handle, &descriptor);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle uart add descriptor fail, ret:%x\r\n", SLE_BEACON_LOG, ret);
        osal_vfree(property.value);
        osal_vfree(descriptor.value);
        return ERRCODE_SLE_FAIL;
    }
    osal_vfree(property.value);
    osal_vfree(descriptor.value);
    return ERRCODE_SLE_SUCCESS;
}

static errcode_t sle_uart_server_add(void)
{
    errcode_t ret;
    sle_uuid_t app_uuid = {0};
    sample_at_log_print("%s sle uart add service in\r\n", SLE_BEACON_LOG);
    app_uuid.len = sizeof(g_sle_uuid_app_uuid);
    if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK)
    {
        return ERRCODE_SLE_FAIL;
    }
    ssapsRegisterServer(&app_uuid, &g_server_id);

    if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS)
    {
       SsapsUnregisterServer(g_server_id);
        return ERRCODE_SLE_FAIL;
    }
    if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS)
    {
        SsapsUnregisterServer(g_server_id);
        return ERRCODE_SLE_FAIL;
    }
    sample_at_log_print("%s sle uart add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", SLE_BEACON_LOG, g_server_id, g_service_handle, g_property_handle);
    ret = SsapsStartService(g_server_id, g_service_handle);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle uart add service fail, ret:%x\r\n", SLE_BEACON_LOG, ret);
        return ERRCODE_SLE_FAIL;
    }
    sample_at_log_print("%s sle uart add service out\r\n", SLE_BEACON_LOG);
    return ERRCODE_SLE_SUCCESS;
}

errcode_t sle_uart_server_send_report_by_handle(const uint8_t *data, uint8_t len)
{
    SsapsNtfInd param = {0};
    uint8_t receive_buf[UART_BUFF_LENGTH] = { 0 };
    param.handle = g_property_handle;
    param.type = SSAP_PROPERTY_TYPE_VALUE;
    param.value = receive_buf;
    param.valueLen = len+1;
    if (memcpy_s(param.value, param.valueLen, data, len) != EOK)
    {
        return ERRCODE_SLE_FAIL;
    }
    return  SsapsNotifyIndicate(g_server_id, g_sle_conn_hdl, &param);
}

static void sle_connect_state_changed_cbk(uint16_t conn_id, const SleAddr *addr, SleAcbStateType conn_state, SlePairStateType pair_state, SleDiscReasonType disc_reason)
{
    uint8_t sle_connect_state[] = "sle_dis_connect";
    sample_at_log_print("%s connect state changed callback conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, disc_reason:0x%x\r\n", SLE_BEACON_LOG,conn_id, conn_state, pair_state, disc_reason);
    sample_at_log_print("%s connect state changed callback addr:%02x:**:**:**:%02x:%02x\r\n", SLE_BEACON_LOG, addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4]);
    if (conn_state == OH_SLE_ACB_STATE_CONNECTED)
    {
        g_sle_conn_hdl = conn_id;
      
    } else if (conn_state == OH_SLE_ACB_STATE_DISCONNECTED)
    {
        g_sle_conn_hdl = 0;
        g_sle_pair_hdl = 0;
        if (g_sle_uart_server_msg_queue != NULL)
        {
            g_sle_uart_server_msg_queue(sle_connect_state, sizeof(sle_connect_state));
        }
    }
}

static void sle_pair_complete_cbk(uint16_t conn_id, const SleAddr *addr, errcode_t status)
{
    sample_at_log_print("%s pair complete conn_id:%02x, status:%x\r\n", SLE_BEACON_LOG, conn_id, status);
    sample_at_log_print("%s pair complete addr:%02x:**:**:**:%02x:%02x\r\n", SLE_BEACON_LOG, addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4]);
    g_sle_pair_hdl = conn_id + 1;

}

static errcode_t sle_conn_register_cbks(void)
{
    errcode_t ret;
    SleConnectionCallbacks conn_cbks = {0};
    conn_cbks.connectStateChangedCb = sle_connect_state_changed_cbk;
    conn_cbks.pairCompleteCb = sle_pair_complete_cbk;
    ret = SleConnectionRegisterCallbacks(&conn_cbks);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_conn_register_cbks,sle_connection_register_callbacks fail :%x\r\n",
        SLE_BEACON_LOG, ret);
        return ret;
    }
    return ERRCODE_SLE_SUCCESS;
}

void ssaps_read_request_callbacks(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, errcode_t status)
{
    (void)server_id;
    (void)conn_id;
    (void)read_cb_para;
    (void)status;
}

void ssaps_write_request_callbacks(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, errcode_t status)
{
    (void)server_id;
    (void)conn_id;
    (void)status;
    write_cb_para->value[write_cb_para->length-1] = '\0';
    printf("client_send_data: %s\r\n",write_cb_para->value);
    char CONTROLLERBack[8] = {0};
    strncpy(CONTROLLERBack, write_cb_para->value, 7);
    CONTROLLERBack[7] = '\0';
    //printf("CONTROLLER:%s\r\n",CONTROLLERBack);
    if(strcmp(CONTROLLERBack,"SOSCall")==0)
    {
        //printf("SOSCall");
        SOSCall();
    }
}

errcode_t sle_init()
{
    errcode_t ret;
    ret = sle_uart_announce_register_cbks();
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,sle_uart_announce_register_cbks fail :%x\r\n",
        SLE_BEACON_LOG, ret);
        return ret;
    }
    ret = sle_conn_register_cbks();
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,sle_conn_register_cbks fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    ret = sle_ssaps_register_cbks(ssaps_read_request_callbacks, ssaps_write_request_callbacks);
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,sle_ssaps_register_cbks fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    ret = EnableSle();
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,enable_sle fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    sample_at_log_print("%s init ok\r\n", SLE_BEACON_LOG);
    return ERRCODE_SLE_SUCCESS;
}

errcode_t sle_enable_server_cbk(void)
{
    errcode_t ret;
    ret = sle_uart_server_add();
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,sle_uart_server_add fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    ret = sle_uart_server_adv_init();
    if (ret != ERRCODE_SLE_SUCCESS)
    {
        sample_at_log_print("%s sle_init,sle_uart_server_adv_init fail :%x\r\n", SLE_BEACON_LOG, ret);
        return ret;
    }
    return ERRCODE_SLE_SUCCESS;
}

void sle_uart_server_register_msg(sle_uart_server_msg_queue sle_uart_server_msg)
{
    g_sle_uart_server_msg_queue = sle_uart_server_msg;
}

int uart_sle_send_data(uint8_t *data,uint8_t length)
{
    int ret;
    ret = sle_uart_server_send_report_by_handle(data,length);
    return ret ;
}

static void *Satellite_task(const char *arg)
{
    (void)arg;
    TaskMsleep(DELAY_1000MS);
    printf("Satellite_task...\r\n");
    // 初始化GPIO
    IoTGpioInit(BEEP_PIN);
    IoTGpioInit(LED_PIN);
    // 设置引脚功能为MODE_0(GPIO)
    IoSetFunc(BEEP_PIN, IOT_IO_FUNC_GPIO_12_GPIO);
    IoSetFunc(LED_PIN, IOT_IO_FUNC_GPIO_14_GPIO);
    // 设置GPIO为输出方向
    IoTGpioSetDir(BEEP_PIN, IOT_GPIO_DIR_OUT);
    IoTGpioSetDir(LED_PIN, IOT_GPIO_DIR_OUT);
    // 配置GPIO引脚号和输出值
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    // 开机功能检测
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE0);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE0);
    TaskMsleep(DELAY_200MS);
    IoTGpioSetOutputVal(BEEP_PIN, IOT_GPIO_VALUE1);
    IoTGpioSetOutputVal(LED_PIN, IOT_GPIO_VALUE1);
    TaskMsleep(DELAY_200MS);
    sle_init();
    TaskMsleep(DELAY_200MS);
    Satellite_config();
    TaskMsleep(DELAY_200MS);
    return NULL;
}

static void SLE_BEACON_entry(void)
{
    osThreadAttr_t attr = {0}; 
    printf("[SLE_BEACON] SLE_BEACON_Entry\r\n"); 
    attr.name = "Satellite_task"; 
    attr.attr_bits = 0U; 
    attr.cb_mem = NULL; 
    attr.cb_size = 0U; 
    attr.stack_mem = NULL; 
    attr.stack_size = 2048 * 10;
    attr.priority = 25;
    
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t)Satellite_task, NULL, &attr) == NULL) 
    { 
        printf("[Satellite] Falied to create Satellite_task!\r\n"); 
    }
    else  printf("[[Satellite] create Satellite_task]\r\n");
}
SYS_RUN(SLE_BEACON_entry);